//-----------------------------------------------------------------------------
// Name: Display.cpp
// Auth: Bradford J. Smith
// Desc: methods and data for display
//-----------------------------------------------------------------------------

#include <windows.h>
#include "Display.h"

#include "Assert.h"
#include "Billboard.h"
#include "DisplayManager.h"
#include "InputManager.h"
#include "SharedConstants.h"
#include "Player.h"
#include "LittleGuy.h"
#include "Systems.h"
#include "TuningParser.h"
#include <list>

//-----------------------------------------------------------------------------
// Globals:
//-----------------------------------------------------------------------------
DWORD gLastTickCount = 0;

const int kElapsedMSHistorySize = 30;
std::list< int > gElapsedMSHistory;

//-----------------------------------------------------------------------------
// Constants:
//-----------------------------------------------------------------------------
static const DWORD kUpdateTimeMS = 200;

//-----------------------------------------------------------------------------
// Function Definitions:
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
void DrawFPSCounter()
{
	// change to a simple 2D perspective for rendering text
	glDisable(GL_DEPTH_TEST);
	glDisable(GL_LIGHTING);
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	{
		glLoadIdentity();
		glMatrixMode(GL_PROJECTION);
		glPushMatrix();
		{
			glLoadIdentity();
			glOrtho(0.0f, GetDisplayManager()->GetWindowWidth(), 0.0f, GetDisplayManager()->GetWindowHeight(), -1.0f, 1.0f);


			static DWORD lastTick = 0;
			int elapsedTimeMS = (int)(GetTickCount() - lastTick);
			gElapsedMSHistory.push_back(elapsedTimeMS);

			// maintain the size of the list.
			if (gElapsedMSHistory.size() > kElapsedMSHistorySize)
			{
				gElapsedMSHistory.pop_front();
			}

			// only do the math and display once we've filled the history
			int historySize = (int)gElapsedMSHistory.size();
			if (historySize == kElapsedMSHistorySize)
			{
				// average the milliseconds per frame
				float totalElapsedMS = 0.0f;
				std::list< int >::iterator iter = gElapsedMSHistory.begin();
				std::list< int >::iterator listEnd = gElapsedMSHistory.end();
				for (iter; iter != listEnd; ++iter)
				{
					totalElapsedMS += *iter;
				}
				float averageMSPF = totalElapsedMS / historySize;


				float averageFPS = historySize / (totalElapsedMS / 1000.0f);

				lastTick = GetTickCount();


				glColor3fv(kColorBlack);
				glRasterPos2i(5, GetDisplayManager()->GetWindowHeight() - 10);
				char buff[64];
				sprintf_s(buff, 64, "%.1f FPS %.1f MSPF", averageFPS, averageMSPF);
				for (unsigned int i = 0; i < strlen(buff);i++)
				{
					glutBitmapCharacter(GLUT_BITMAP_9_BY_15, buff[i]);
				}
			}
		}
		glPopMatrix();
	}
	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();
}

void ReshapeFunction(GLsizei w, GLsizei h)
{
	// update the data in the display manager
	cDisplayManager* pDisplayManager = GetDisplayManager();
	pDisplayManager->SetWindowArea(w, h);

	// update the viewport within the window
	glViewport(0, 0, w, h);

	pDisplayManager->UpdateProjection();
}

//-----------------------------------------------------------------------------
void DisplayFunction()
{
	cDisplayManager* pDisplayManager = GetDisplayManager();
	Assert(pDisplayManager != NULL);

	// clear the buffers
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	pDisplayManager->DrawDebugAxes();

	// Update the camera
	pDisplayManager->UpdateCamera();	


	// think

	// if enough time has elapsed
	if (GetTickCount() - gLastTickCount > kUpdateTimeMS)
	{
		// update whatever it is you need to update...

		// reset the last time recorded that we did an update
		gLastTickCount = GetTickCount();
	}

	// draw
  ///player jet
	cPlayer* pPlayer = GetPlayer();
	if (pPlayer)
	{
		pPlayer->Draw();
	}

  ///player bullet
  for ( int i = 0 ; i < 20 ; i++ )
  {
    pPlayer->getRBullet(i)->draw();
    pPlayer->getLBullet(i)->draw();
  }

  /////////////////////Little Guy testing/////////////////////////
  ///LittleGuy jet
  cLittleGuy* pLittleGuy = GetLittleGuy();
  pLittleGuy->Draw();

  ///LittleGuy Bullet
  for ( int i = 0 ; i < 20 ; i++ )
  {
    pLittleGuy->getRBullet(i)->draw();
    pLittleGuy->getLBullet(i)->draw();
  }
  /////////////////////Little Guy testing/////////////////////////

  ///Billboard Background
  cBillboard* pBillboard = GetBillboard();
  if (pBillboard)
  {
	  pBillboard->Draw();
  }

  glutSetCursor(GLUT_CURSOR_CROSSHAIR);
  DrawFPSCounter();

	// flip the buffer to the screen
	glFlush();
	glutSwapBuffers();
}
